-
Notifications
You must be signed in to change notification settings - Fork 19
[WEB-3694] Custom CT ID & Get All Qualified Campaigns #408
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
🧹 Nitpick comments (9)
src/modules/device.js (1)
12-12: Remove debugging console.log statement.A console.log statement has been left in the code which should be removed before production release.
- console.log('this.gcookie', this.gcookie)src/util/tr.js (2)
31-31: Verify that import order is consistent with project standards.The new import
addCampaignToLocalStoragehas been added to an existing import list. Make sure this follows the project's import ordering conventions.
38-41: Add a parameter comment to document theregionparameter.The
_trfunction signature has been updated to accept aregionparameter, but it's not documented in the function's comments. Consider adding a comment to explain its purpose and expected type.const _tr = (msg, { device, session, request, logger, + // region: The account region for tracking campaigns region }) => {Also applies to: 45-47
src/util/helpers.js (1)
138-153: LGTM! Good prefix implementation but consider making this public.The
addWebPrefixfunction properly enforces type checking and prefixes the ID with the platform-specific prefix. However, since this is a helper function that might be needed elsewhere, consider making it exported rather than private.This could be exported as a named export if other parts of the SDK need to use this function directly.
-function addWebPrefix (id) { +export function addWebPrefix (id) {clevertap.js (5)
155-156: Consider future-proofing the qualified-campaigns cookie.
QUALIFIED_CAMPAIGNSis introduced as a dedicated cookie/local-storage key, which is great.
However, because this array is being appended to indefinitely (seeaddCampaignToLocalStorage), it can quickly exceed both cookie-size limits (~4 KB) and local-storage quotas (5–10 MB, but shared per-origin). A rolling window (e.g. last N campaigns or max age) will avoid silent write failures and corrupted values.
222-223: Prefix constant looks good – minor naming nit.
CUSTOM_CT_ID_PREFIXis clear and self-explanatory. As it is web-specific, considerWEB_CUSTOM_CT_ID_PREFIXto mirror Android/iOS constants and avoid cross-platform confusion.
Nothing blocking.
12624-12688: Validation helper is solid – two minor tweaks.
allowedPatternneed not allow upper-case because we already lowercase the input.- The function returns
{error}when invalid, yet callers logsanitizedId, leading toundefinedmessages (see next comment). Exporting theerrormakes troubleshooting easier.- const allowedPattern = /^[a-z0-9()!:@$_-]+$/; + const allowedPattern = /^[a-z0-9()!:@$_-]+$/; // lower-case onlyand ensure consumers read
error.
17018-17020: Invocation order good, but propagate validation errors.
createCustomIdIfValidis called after updating account context – good. Consider bubbling up the error return to callers (or throwing) so integrators can surface invalid IDs in their own logs/UI instead of the SDK silently swallowing them.
17246-17249: Return a safe default rather thanundefined.
getAllQualifiedCampaignDetailsyieldsundefinedwhen nothing is stored.
Returning[]makes client-side handling cleaner:- const existingCampaign = StorageManager.readFromLSorCookie(QUALIFIED_CAMPAIGNS) && JSON.parse(...); - return existingCampaign; + const stored = StorageManager.readFromLSorCookie(QUALIFIED_CAMPAIGNS); + return stored ? JSON.parse(decodeURIComponent(stored)) : [];
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
clevertap.js.mapis excluded by!**/*.mapclevertap.min.jsis excluded by!**/*.min.js
📒 Files selected for processing (8)
clevertap.js(15 hunks)src/clevertap.js(7 hunks)src/modules/device.js(1 hunks)src/modules/web-inbox/Message.js(1 hunks)src/util/campaignRender/utilities.js(2 hunks)src/util/constants.js(2 hunks)src/util/helpers.js(2 hunks)src/util/tr.js(3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
src/util/constants.js (1)
clevertap.js (2)
QUALIFIED_CAMPAIGNS(155-155)CUSTOM_CT_ID_PREFIX(222-222)
src/util/helpers.js (1)
src/util/constants.js (2)
CUSTOM_CT_ID_PREFIX(72-72)CUSTOM_CT_ID_PREFIX(72-72)
src/util/campaignRender/utilities.js (2)
src/util/storage.js (1)
StorageManager(9-246)src/util/constants.js (2)
QUALIFIED_CAMPAIGNS(9-9)QUALIFIED_CAMPAIGNS(9-9)
🪛 GitHub Actions: Test and build
src/clevertap.js
[error] 108-108: TypeError: Cannot read properties of undefined (reading 'isValid') in constructor and multiple init tests. This error occurs repeatedly at line 108 in src/clevertap.js during test/unit/clevertap.spec.js tests.
clevertap.js
[error] 108-108: TypeError: Cannot read properties of undefined (reading 'isValid') in constructor and multiple init tests. This error occurs repeatedly at line 108 in src/clevertap.js during test/unit/clevertap.spec.js tests.
🔇 Additional comments (18)
src/util/constants.js (2)
9-9: New constant added for qualified campaigns storage.The
QUALIFIED_CAMPAIGNSconstant defines the key for storing qualified campaign data in local storage. This aligns with the PR objective to implement a new public API method for retrieving qualified campaign details during debugging.
72-72: New constant added for custom CleverTap ID prefix.The
CUSTOM_CT_ID_PREFIXconstant defines the platform-specific prefix ('w') for custom CleverTap IDs. This supports the PR objective to add custom CleverTap ID functionality.src/util/campaignRender/utilities.js (2)
13-14: Added required imports for new functionality.Importing the necessary constants to support the new campaign storage functionality and visual editor types.
356-377: Well-implemented campaign storage functionality.This function enriches campaign objects with dashboard URLs and persists them to local storage, with proper duplicate prevention. It successfully implements part of the PR objective to support retrieving qualified campaign details for debugging.
The implementation correctly:
- Extracts the campaign ID from the
wzrk_id- Constructs a dashboard URL using region and accountId
- Prevents duplicate entries by checking existing campaigns
- Uses proper encoding/decoding for storage
src/modules/web-inbox/Message.js (1)
8-8: Added null check for renderMessage call.This defensive programming change ensures the
renderMessagemethod is only called when a message is actually provided, preventing potential errors when the message parameter is null or undefined.src/modules/device.js (2)
9-9: Updated constructor to accept customId parameter.Constructor now accepts an object with both
loggerandcustomIdproperties, supporting the custom CleverTap ID feature from the PR objectives.
11-11: Added fallback logic for custom CleverTap ID.This line correctly implements the fallback mechanism for custom IDs, using the existing GUID if available and falling back to the custom ID if not.
src/util/tr.js (2)
849-850: LGTM! Campaign tracking implementation.The implementation correctly passes the campaign, region, and account ID to
addCampaignToLocalStoragefor in-app notifications.
935-936: LGTM! Campaign tracking for inbox notifications.The implementation correctly passes inbox notifications to
addCampaignToLocalStorage, consistent with the in-app notification implementation.src/util/helpers.js (2)
1-2: LGTM! Good import practice for constants.Importing the constant from the constants file follows good practices for maintainability.
99-136: LGTM! Well-documented and thorough validation function.The
validateCustomCleverTapIDfunction is well-documented with clear comments about the validation rules. It properly handles validation for:
- Input type (must be a string)
- Length constraints (1-64 characters)
- Allowed characters (using a regex pattern)
The function returns an object with validation results, error messages, and a sanitized ID, which is a good pattern.
src/clevertap.js (6)
36-38: LGTM! Good import practice for constants.Adding imports for the new constants needed for this feature.
658-673: LGTM! Well-implemented custom ID creation logic.The
createCustomIdIfValidmethod provides a clean way to validate and set custom IDs. It correctly:
- Validates the custom ID
- Checks if a device GUID already exists before applying the custom ID
- Updates both the in-memory representation and local storage
- Provides appropriate logging
675-677: LGTM! Good implementation of config handling in init.The modified
initmethod now properly accepts and processes the optional config parameter with antiFlicker and customId properties.
712-713: LGTM! Call to create custom ID in init method.Calling
createCustomIdIfValidin the init method ensures that custom IDs can be set during initialization.
593-595: LGTM! Added region to tr function call.Properly forwarding the account region to the
_trfunction which enables region-aware campaign tracking.
1034-1041: LGTM! Well-implemented campaign details retrieval method.The
getAllQualifiedCampaignDetailsmethod is well-documented and provides a clean way to access campaign details for debugging purposes. It correctly reads from local storage, parses the JSON, and returns the decoded campaign information.clevertap.js (1)
10071-10075: Constructor guard improves stability – LGTM.
Rendering only when a message exists prevents a handful of null-pointer paths observed in earlier builds.
src/clevertap.js
Outdated
| if (!this.#device.gcookie) { | ||
| return | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logic error in GUID check - inverted condition
The current condition exits the function if the GUID exists, but the comment indicates that we should only add a custom ID if no existing ID is present. The condition appears to be inverted.
Correct the condition to match the intended behavior:
/* Only add Custom Id if no existing id is present */
- if (!this.#device.gcookie) {
+ if (this.#device.gcookie) {
return
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (!this.#device.gcookie) { | |
| return | |
| } | |
| /* Only add Custom Id if no existing id is present */ | |
| if (this.#device.gcookie) { | |
| return | |
| } |
|
|
||
| const { isValid, sanitizedId } = validateCustomCleverTapID(clevertap.config?.customId) | ||
| if (!isValid) { | ||
| this.#logger.error(sanitizedId) | ||
| } | ||
|
|
||
| this.#device = new DeviceManager({ logger: this.#logger, customId: isValid ? sanitizedId : null }) | ||
| this.#dismissSpamControl = clevertap.dismissSpamControl || false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix potential undefined error when accessing config properties.
There's a pipeline failure here where the code attempts to access properties of potentially undefined objects. The optional chaining on clevertap.config?.customId is correct, but it appears validateCustomCleverTapID might be receiving undefined and trying to destructure properties from the result.
Apply this fix to handle cases where the config is not provided:
- const { isValid, sanitizedId } = validateCustomCleverTapID(clevertap.config?.customId)
- if (!isValid) {
- this.#logger.error(sanitizedId)
+ let isValid = false;
+ let sanitizedId = null;
+
+ if (clevertap.config?.customId) {
+ const result = validateCustomCleverTapID(clevertap.config.customId);
+ isValid = result.isValid;
+ if (!isValid) {
+ this.#logger.error(result.error);
+ } else {
+ sanitizedId = result.sanitizedId;
+ }
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const { isValid, sanitizedId } = validateCustomCleverTapID(clevertap.config?.customId) | |
| if (!isValid) { | |
| this.#logger.error(sanitizedId) | |
| } | |
| this.#device = new DeviceManager({ logger: this.#logger, customId: isValid ? sanitizedId : null }) | |
| this.#dismissSpamControl = clevertap.dismissSpamControl || false | |
| // Guard against missing config.customId | |
| let isValid = false; | |
| let sanitizedId = null; | |
| if (clevertap.config?.customId) { | |
| const result = validateCustomCleverTapID(clevertap.config.customId); | |
| isValid = result.isValid; | |
| if (!isValid) { | |
| this.#logger.error(result.error); | |
| } else { | |
| sanitizedId = result.sanitizedId; | |
| } | |
| } | |
| this.#device = new DeviceManager({ | |
| logger: this.#logger, | |
| customId: isValid ? sanitizedId : null | |
| }); | |
| this.#dismissSpamControl = clevertap.dismissSpamControl || false; |
🧰 Tools
🪛 GitHub Actions: Test and build
[error] 108-108: TypeError: Cannot read properties of undefined (reading 'isValid') in constructor and multiple init tests. This error occurs repeatedly at line 108 in src/clevertap.js during test/unit/clevertap.spec.js tests.
| _classPrivateFieldLooseBase(this, _logger)[_logger] = new Logger(logLevels.INFO); | ||
| _classPrivateFieldLooseBase(this, _account)[_account] = new Account((_clevertap$account = clevertap.account) === null || _clevertap$account === void 0 ? void 0 : _clevertap$account[0], clevertap.region || ((_clevertap$account2 = clevertap.account) === null || _clevertap$account2 === void 0 ? void 0 : _clevertap$account2[1]), clevertap.targetDomain || ((_clevertap$account3 = clevertap.account) === null || _clevertap$account3 === void 0 ? void 0 : _clevertap$account3[2]), clevertap.token || ((_clevertap$account4 = clevertap.account) === null || _clevertap$account4 === void 0 ? void 0 : _clevertap$account4[3])); | ||
| encryption.key = (_clevertap$account5 = clevertap.account) === null || _clevertap$account5 === void 0 ? void 0 : _clevertap$account5[0].id; | ||
| encryption.key = (_clevertap$account5 = clevertap.account) === null || _clevertap$account5 === void 0 ? void 0 : _clevertap$account5[0].id; // Custom Guid will be set here | ||
|
|
||
| const { | ||
| isValid, | ||
| sanitizedId | ||
| } = validateCustomCleverTapID((_clevertap$config = clevertap.config) === null || _clevertap$config === void 0 ? void 0 : _clevertap$config.customId); | ||
|
|
||
| if (!isValid) { | ||
| _classPrivateFieldLooseBase(this, _logger)[_logger].error(sanitizedId); | ||
| } | ||
|
|
||
| _classPrivateFieldLooseBase(this, _device)[_device] = new DeviceManager({ | ||
| logger: _classPrivateFieldLooseBase(this, _logger)[_logger] | ||
| logger: _classPrivateFieldLooseBase(this, _logger)[_logger], | ||
| customId: isValid ? sanitizedId : null | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect error logging & potential source of the unit-test failure.
When the supplied customId is invalid, the destructuring yields sanitizedId = undefined, so
_logger.error(sanitizedId); // logs "undefined"Meanwhile later code assumes isValid exists, which it will, but any earlier refactor that returns undefined would reproduce the pipeline error. Prefer logging the error string returned by the validator:
- const { isValid, sanitizedId } = validateCustomCleverTapID(...);
+ const { isValid, sanitizedId, error } = validateCustomCleverTapID(...);
if (!isValid) {
- _classPrivateFieldLooseBase(this, _logger)[_logger].error(sanitizedId);
+ _classPrivateFieldLooseBase(this, _logger)[_logger].error(error);
}| let { | ||
| logger | ||
| logger, | ||
| customId | ||
| } = _ref; | ||
| Object.defineProperty(this, _logger$9, { | ||
| writable: true, | ||
| value: void 0 | ||
| }); | ||
| this.gcookie = void 0; | ||
| _classPrivateFieldLooseBase(this, _logger$9)[_logger$9] = logger; | ||
| this.gcookie = this.getGuid(); | ||
| this.gcookie = this.getGuid() || customId; | ||
| console.log('this.gcookie', this.gcookie); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Avoid unconditional console logging & clarify precedence of IDs.
-
console.log('this.gcookie', this.gcookie);will leak into production bundles. Use the injectedloggerso the SDK honours the consumer’s log-level. -
this.gcookie = this.getGuid() || customId;gives priority to the stored GUID and uses the custom ID only when none exists – correct according to the PR description.
‑ If the intention is the inverse (always honour the supplied custom ID), swap the operands.
- this.gcookie = this.getGuid() || customId;
- console.log('this.gcookie', this.gcookie);
+ // prefer existing guid; fall back to validated customId
+ this.gcookie = this.getGuid() || customId;
+ _classPrivateFieldLooseBase(this, _logger$9)[_logger$9].debug('Device GUID set to', this.gcookie);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| let { | |
| logger | |
| logger, | |
| customId | |
| } = _ref; | |
| Object.defineProperty(this, _logger$9, { | |
| writable: true, | |
| value: void 0 | |
| }); | |
| this.gcookie = void 0; | |
| _classPrivateFieldLooseBase(this, _logger$9)[_logger$9] = logger; | |
| this.gcookie = this.getGuid(); | |
| this.gcookie = this.getGuid() || customId; | |
| console.log('this.gcookie', this.gcookie); | |
| } | |
| let { | |
| logger, | |
| customId | |
| } = _ref; | |
| Object.defineProperty(this, _logger$9, { | |
| writable: true, | |
| value: void 0 | |
| }); | |
| this.gcookie = void 0; | |
| _classPrivateFieldLooseBase(this, _logger$9)[_logger$9] = logger; | |
| // prefer existing guid; fall back to validated customId | |
| this.gcookie = this.getGuid() || customId; | |
| _classPrivateFieldLooseBase(this, _logger$9)[_logger$9].debug('Device GUID set to', this.gcookie); | |
| } |
| createCustomIdIfValid(customId) { | ||
| const { | ||
| isValid, | ||
| sanitizedId | ||
| } = validateCustomCleverTapID(customId); | ||
| /* Only add Custom Id if no existing id is present */ | ||
|
|
||
| if (!_classPrivateFieldLooseBase(this, _device)[_device].gcookie) { | ||
| return; | ||
| } | ||
|
|
||
| if (isValid) { | ||
| _classPrivateFieldLooseBase(this, _device)[_device].gcookie = sanitizedId; | ||
| StorageManager.saveToLSorCookie(GCOOKIE_NAME, sanitizedId); | ||
|
|
||
| _classPrivateFieldLooseBase(this, _logger)[_logger].debug('CT Initialized with customId:: ' + sanitizedId); | ||
| } else { | ||
| _classPrivateFieldLooseBase(this, _logger)[_logger].error('Invalid customId'); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Logic inverted – custom ID never persisted for first-time users.
The guard clause returns when no gcookie exists, contrary to the comment:
- /* Only add Custom Id if no existing id is present */
- if (!_classPrivateFieldLooseBase(this, _device)[_device].gcookie) {
- return;
- }
+ /* Only add Custom Id if no existing id is present */
+ if (_classPrivateFieldLooseBase(this, _device)[_device].gcookie) {
+ return; // GUID already present – leave untouched
+ }This bug prevents the custom ID from being stored on fresh installs and matches the test failures reporting isValid as undefined.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| createCustomIdIfValid(customId) { | |
| const { | |
| isValid, | |
| sanitizedId | |
| } = validateCustomCleverTapID(customId); | |
| /* Only add Custom Id if no existing id is present */ | |
| if (!_classPrivateFieldLooseBase(this, _device)[_device].gcookie) { | |
| return; | |
| } | |
| if (isValid) { | |
| _classPrivateFieldLooseBase(this, _device)[_device].gcookie = sanitizedId; | |
| StorageManager.saveToLSorCookie(GCOOKIE_NAME, sanitizedId); | |
| _classPrivateFieldLooseBase(this, _logger)[_logger].debug('CT Initialized with customId:: ' + sanitizedId); | |
| } else { | |
| _classPrivateFieldLooseBase(this, _logger)[_logger].error('Invalid customId'); | |
| } | |
| } | |
| createCustomIdIfValid(customId) { | |
| const { | |
| isValid, | |
| sanitizedId | |
| } = validateCustomCleverTapID(customId); | |
| /* Only add Custom Id if no existing id is present */ | |
| if (_classPrivateFieldLooseBase(this, _device)[_device].gcookie) { | |
| return; // GUID already present – leave untouched | |
| } | |
| if (isValid) { | |
| _classPrivateFieldLooseBase(this, _device)[_device].gcookie = sanitizedId; | |
| StorageManager.saveToLSorCookie(GCOOKIE_NAME, sanitizedId); | |
| _classPrivateFieldLooseBase(this, _logger)[_logger].debug('CT Initialized with customId:: ' + sanitizedId); | |
| } else { | |
| _classPrivateFieldLooseBase(this, _logger)[_logger].error('Invalid customId'); | |
| } | |
| } |
| function addCampaignToLocalStorage(campaign) { | ||
| let region = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'eu1'; | ||
| let accountId = arguments.length > 2 ? arguments[2] : undefined; | ||
| const campaignId = campaign.wzrk_id.split('_')[0]; | ||
| const dashboardUrl = "https://".concat(region, ".dashboard.clevertap.com/").concat(accountId, "/campaigns/campaign/").concat(campaignId, "/report/stats"); | ||
| const enrichedCampaign = { ...campaign, | ||
| url: dashboardUrl | ||
| }; | ||
| const storedData = StorageManager.readFromLSorCookie(QUALIFIED_CAMPAIGNS); | ||
| const existingCampaigns = storedData ? JSON.parse(decodeURIComponent(storedData)) : []; | ||
| const isDuplicate = existingCampaigns.some(c => c.wzrk_id === campaign.wzrk_id); | ||
|
|
||
| if (!isDuplicate) { | ||
| const updatedCampaigns = [...existingCampaigns, enrichedCampaign]; | ||
| StorageManager.saveToLSorCookie(QUALIFIED_CAMPAIGNS, encodeURIComponent(JSON.stringify(updatedCampaigns))); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Harden local-storage deserialisation & enforce a retention policy.
decodeURIComponent and JSON.parse will throw if the stored value is malformed (e.g. user manually clears part of the cookie). A defensive wrapper avoids cascading failures:
- const storedData = StorageManager.readFromLSorCookie(QUALIFIED_CAMPAIGNS);
- const existingCampaigns = storedData ? JSON.parse(decodeURIComponent(storedData)) : [];
+ let existingCampaigns = [];
+ try {
+ const storedData = StorageManager.readFromLSorCookie(QUALIFIED_CAMPAIGNS);
+ existingCampaigns = storedData ? JSON.parse(decodeURIComponent(storedData)) : [];
+ } catch (e) {
+ existingCampaigns = [];
+ logger$1?.warn('Corrupted QUALIFIED_CAMPAIGNS payload – resetting.', e);
+ }Optional: cap the array length (e.g. 50) before saving to respect storage limits (see previous comment).
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| function addCampaignToLocalStorage(campaign) { | |
| let region = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'eu1'; | |
| let accountId = arguments.length > 2 ? arguments[2] : undefined; | |
| const campaignId = campaign.wzrk_id.split('_')[0]; | |
| const dashboardUrl = "https://".concat(region, ".dashboard.clevertap.com/").concat(accountId, "/campaigns/campaign/").concat(campaignId, "/report/stats"); | |
| const enrichedCampaign = { ...campaign, | |
| url: dashboardUrl | |
| }; | |
| const storedData = StorageManager.readFromLSorCookie(QUALIFIED_CAMPAIGNS); | |
| const existingCampaigns = storedData ? JSON.parse(decodeURIComponent(storedData)) : []; | |
| const isDuplicate = existingCampaigns.some(c => c.wzrk_id === campaign.wzrk_id); | |
| if (!isDuplicate) { | |
| const updatedCampaigns = [...existingCampaigns, enrichedCampaign]; | |
| StorageManager.saveToLSorCookie(QUALIFIED_CAMPAIGNS, encodeURIComponent(JSON.stringify(updatedCampaigns))); | |
| } | |
| } | |
| function addCampaignToLocalStorage(campaign) { | |
| let region = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'eu1'; | |
| let accountId = arguments.length > 2 ? arguments[2] : undefined; | |
| const campaignId = campaign.wzrk_id.split('_')[0]; | |
| const dashboardUrl = "https://".concat(region, ".dashboard.clevertap.com/").concat(accountId, "/campaigns/campaign/").concat(campaignId, "/report/stats"); | |
| const enrichedCampaign = { ...campaign, | |
| url: dashboardUrl | |
| }; | |
| - const storedData = StorageManager.readFromLSorCookie(QUALIFIED_CAMPAIGNS); | |
| - const existingCampaigns = storedData ? JSON.parse(decodeURIComponent(storedData)) : []; | |
| + let existingCampaigns = []; | |
| + try { | |
| + const storedData = StorageManager.readFromLSorCookie(QUALIFIED_CAMPAIGNS); | |
| + existingCampaigns = storedData ? JSON.parse(decodeURIComponent(storedData)) : []; | |
| + } catch (e) { | |
| + existingCampaigns = []; | |
| + logger$1?.warn('Corrupted QUALIFIED_CAMPAIGNS payload – resetting.', e); | |
| + } | |
| const isDuplicate = existingCampaigns.some(c => c.wzrk_id === campaign.wzrk_id); | |
| if (!isDuplicate) { | |
| const updatedCampaigns = [...existingCampaigns, enrichedCampaign]; | |
| StorageManager.saveToLSorCookie(QUALIFIED_CAMPAIGNS, encodeURIComponent(JSON.stringify(updatedCampaigns))); | |
| } | |
| } |
4ffa46f to
34af2a9
Compare
3af1342 to
696793b
Compare
| } | ||
| } | ||
|
|
||
| init (accountId, region, targetDomain, token, config = { antiFlicker: {}, customId: null }) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not change any existing parameters. This would be a breaking change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have checked with the PM on this in the past, the antiflicker param is not being used by any customer and hence its format can be changed.
Refer : #368 (comment)

Changes
clevertap.getAllQualifiedCampaignDetails()for getting all qualified campaign details durign debuggingChanges to Public Facing API if any
How Has This Been Tested?
getAllQualifiedCampaignDetailsto get their details during debugging in consoleChecklist
Summary by CodeRabbit
New Features
Bug Fixes
Chores